package com.york.jobmew.auth.application.controller;

import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.google.common.base.Preconditions;
import com.york.jobmew.auth.application.convert.AuthUserDTOConverter;
//import com.york.jobmew.auth.application.utils.DeviceUtils;
import com.york.jobmew.auth.domain.entity.AuthUserBO;
import com.york.jobmew.auth.domain.exception.UserException;
import com.york.jobmew.auth.domain.service.AuthUserDomainService;
import com.york.jobmew.auth.entity.AuthUserDTO;
import com.york.jobmew.auth.entity.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
//import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * 用户Controller
 */
@RestController
@RequestMapping("/user/")
@Slf4j
public class UserController {

    @Resource
    private AuthUserDomainService authUserDomainService;

    /**
     * 用户注册
     */
    @RequestMapping("register")
    public Result<Boolean> register(@RequestBody AuthUserDTO authUserDTO) {
        try {
            checkUserInfo(authUserDTO);
            AuthUserBO authUserBO = AuthUserDTOConverter.INSTANCE.convertDTOToBO(authUserDTO);
            return Result.ok(authUserDomainService.register(authUserBO));
        } catch (UserException e) {
            return Result.fail(e.getMessage());
        } catch (Exception e) {
            return Result.fail("注册用户失败");
        }
    }

    /**
     * 修改用户信息
     */
    @RequestMapping("update")
    public Result<Boolean> update(@RequestBody AuthUserDTO authUserDTO) {
        try {
            checkUserInfo(authUserDTO);
            AuthUserBO authUserBO = AuthUserDTOConverter.INSTANCE.convertDTOToBO(authUserDTO);
            return Result.ok(authUserDomainService.update(authUserBO));
        } catch (Exception e) {
            return Result.fail("更新用户信息失败");
        }
    }

    /**
     * 获取用户信息
     */
    @RequestMapping("getUserInfo")
    public Result<AuthUserDTO> getUserInfo(@RequestBody AuthUserDTO authUserDTO) {
        try {
            Preconditions.checkArgument(!StringUtils.isBlank(authUserDTO.getUserName()), "用户名不能为空");
            AuthUserBO authUserBO = AuthUserDTOConverter.INSTANCE.convertDTOToBO(authUserDTO);
            AuthUserBO userInfo = authUserDomainService.getUserInfo(authUserBO);
            return Result.ok(AuthUserDTOConverter.INSTANCE.convertBOToDTO(userInfo));
        } catch (Exception e) {
            return Result.fail("获取用户信息失败");
        }
    }

    /**
     * 批量获取用户信息
     */
    @RequestMapping("listByIds")
    public Result<List<AuthUserDTO>> listUserInfoByIds(@RequestBody List<String> userNameList) {
        try {
            Preconditions.checkArgument(!CollectionUtils.isEmpty(userNameList), "id集合不能为空");
            List<AuthUserBO> userInfos = authUserDomainService.listUserInfoByIds(userNameList);
            return Result.ok(AuthUserDTOConverter.INSTANCE.convertBOToDTO(userInfos));
        } catch (Exception e) {
            return Result.fail("批量获取用户信息失败");
        }
    }


    /**
     * 用户退出
     */
    @RequestMapping("logOut")
    public Result logOut(@RequestParam String userName) {
        try {
            Preconditions.checkArgument(!StringUtils.isBlank(userName), "用户名不能为空");
            StpUtil.logout(userName);
            return Result.ok();
        } catch (Exception e) {
            return Result.fail("用户登出失败");
        }
    }

    /**
     * 删除用户
     */
    @RequestMapping("delete")
    public Result<Boolean> delete(@RequestBody AuthUserDTO authUserDTO) {
        try {
            AuthUserBO authUserBO = AuthUserDTOConverter.INSTANCE.convertDTOToBO(authUserDTO);
            return Result.ok(authUserDomainService.update(authUserBO));
        } catch (Exception e) {
            return Result.fail("删除用户信息失败");
        }
    }

    /**
     * 校验
     *
     * @param authUserDTO
     */
    private void checkUserInfo(@RequestBody AuthUserDTO authUserDTO) {
        Preconditions.checkArgument(!StringUtils.isBlank(authUserDTO.getUserName()), "用户名不能为空");
    }

    /**
     * 用户启用/禁用
     */
    @RequestMapping("changeStatus")
    public Result<Boolean> changeStatus(@RequestBody AuthUserDTO authUserDTO) {
        try {
            Preconditions.checkNotNull(authUserDTO.getStatus(), "用户状态不能为空");
            AuthUserBO authUserBO = AuthUserDTOConverter.INSTANCE.convertDTOToBO(authUserDTO);
            return Result.ok(authUserDomainService.update(authUserBO));
        } catch (Exception e) {
            return Result.fail("启用/禁用用户信息失败");
        }
    }

    /**
     * 用户验证码登陆
     *
     * @param validCode 验证码
     * @return
     */
    @RequestMapping("doLogin")
//    public Result<SaTokenInfo> doLogin(@RequestParam("validCode") String validCode, HttpServletRequest request) {
    public Result<SaTokenInfo> doLogin(@RequestParam("validCode") String validCode) {
        try {
            Preconditions.checkArgument(!StringUtils.isBlank(validCode), "验证码不能为空!");
            // 设备工具类，同端登录检测
//            String device = DeviceUtils.getRequestDevice(request);
//            return Result.ok(authUserDomainService.doLogin(validCode, device));
            return Result.ok(authUserDomainService.doLogin(validCode));
        } catch (UserException e) {
            return Result.fail(e.getMessage());
        } catch (Exception e) {
            return Result.fail("用户登录失败");
        }
    }

    /**
     * 用户密码登录
     *
     * @param authUserBO 用户登录信息（包含用户名和密码）
     * @return
     */
    @RequestMapping("doLoginByPassword")
//    public Result<SaTokenInfo> doLoginByPassword(@RequestBody AuthUserBO authUserBO, HttpServletRequest request) {
    public Result<SaTokenInfo> doLoginByPassword(@RequestBody AuthUserBO authUserBO) {
        try {
            // 参数校验
            Preconditions.checkArgument(!StringUtils.isBlank(authUserBO.getUserName()), "用户名不能为空!");
            Preconditions.checkArgument(!StringUtils.isBlank(authUserBO.getPassword()), "密码不能为空!");
            // 设备工具类，同端登录检测
//            String device = DeviceUtils.getRequestDevice(request);
            // 调用业务层进行登录
//            return Result.ok(authUserDomainService.doLoginByPassword(authUserBO, device));
            return Result.ok(authUserDomainService.doLoginByPassword(authUserBO));
        } catch (UserException e) {
            return Result.fail(e.getMessage());
        } catch (Exception e) {
            return Result.fail("用户登录失败");
        }
    }

    /**
     * 获取当前登录用户信息
     *
     * @return 当前用户登录信息
     */
    @GetMapping("getLoginUser")
    public Result<AuthUserDTO> getLoginUser() {
        try {
            // 1. 校验当前会话是否登录（可选，根据业务需求决定是否强制校验）
            if (!StpUtil.isLogin()) {
                return Result.fail("用户未登录");
            }

            // 2. 从SaToken会话中获取用户ID（核心方法）
            String loginId = (String) StpUtil.getLoginId();

            // 3. 根据用户ID查询完整用户信息（需自行实现用户服务层）
            AuthUserBO userInfo = authUserDomainService.getUserByLoginId(loginId);
            return Result.ok(AuthUserDTOConverter.INSTANCE.convertBOToDTO(userInfo));
        } catch (Exception e) {
            return Result.fail("获取用户信息失败: " + e.getMessage());
        }
    }

    /**
     * 添加用户签到记录
     *
     * @return 当前是否已签到成功
     */
    @PostMapping("add/sign_in")
    public Result<Boolean> addUserSignIn() {
        // 必须要登录才能签到
        try {
            Result<AuthUserDTO> res = this.getLoginUser();
            AuthUserDTO loginUser = res.getData();
            return Result.ok(authUserDomainService.addUserSignIn(loginUser.getId()));
        } catch (Exception e) {
            return Result.fail("添加签到记录失败:" + e.getMessage());
        }
    }

    /**
     * 获取用户签到记录
     *
     * @param year 年份（为空表示当前年份）
     * @return 签到记录映射
         */
        @GetMapping("get/sign_in")
        public Result<List<Integer>> getUserSignInRecord(@RequestParam Integer year) {
        // 必须要登录才能获取
        try {
            Result<AuthUserDTO> res = this.getLoginUser();
            AuthUserDTO loginUser = res.getData();
            List<Integer> userSignInRecord = authUserDomainService.getUserSignInRecord(loginUser.getId(), year);
            return Result.ok(userSignInRecord);
        } catch (Exception e) {
            return Result.fail("获取签到记录失败:" + e.getMessage());
        }
    }

}
